using System;
using System.Collections;
using System.Collections.Specialized;
using System.Text;
using Sedna.Core.Controller;
using Sedna.Core.Controller.Common;
using Sedna.DAO;
using Spring.Util;

namespace Sedna.Core.Controls.Actions
{
    public class AttachToSessionAction : AbstractAction
    {
        private IBaseDAO objectDAO;

        private IList objectsToAttach;        
        private IList objectsToUpdate;
        private IList objectsToRefresh;
        
        private bool tryToAttach = true;        
        private bool tryToUpdate = true;

        private bool checkNulls;

        private string collectionPath;
        
        # region Properties

        public string CollectionPath
        {
            set { collectionPath = value; }
        }

        public IBaseDAO ObjectDAO
        {
            get { return objectDAO; }
            set { objectDAO = value; }
        }

        public IList ObjectsToAttach
        {
            get { return objectsToAttach; }
            set { objectsToAttach = value; }
        }

        public IList ObjectsToUpdate
        {
            get { return objectsToUpdate; }
            set { objectsToUpdate = value; }
        }

        public IList ObjectsToRefresh
        {
            get { return objectsToRefresh; }
            set { objectsToRefresh = value; }
        }

        public bool TryToAttach
        {
            set { tryToAttach = value; }
        }

        public bool TryToUpdate
        {
            set { tryToUpdate = value; }
        }

        public bool CheckNulls
        {
            set { checkNulls = value; }
        }

        # endregion

               
        public override IActionResult Execute(IExecutionContext executionContext)
        {
            object entity;

            if (objectsToAttach != null)
            {
                foreach (string objectPath in objectsToAttach)
                {
                    entity = scopePathParser.Parse(objectPath).Value;
                    if (checkNulls && entity == null) continue;


                    if (entity is ICollection)
                    {
                        AttachCollection((ICollection)entity);        
                    } 
                    else
                    {
                        AttachObject(entity);
                    }
                }
            }

            if (objectsToUpdate != null)
            {
                foreach (string objectPath in objectsToUpdate)
                {
                    entity = scopePathParser.Parse(objectPath).Value;

                    if (checkNulls && entity == null)
                        continue;

                    if (tryToUpdate)
                        objectDAO.TryToUpdate(entity);
                    else
                        objectDAO.Update(entity);
                }
            }

            if (ObjectsToRefresh != null)
            {
                foreach (string objectPath in ObjectsToRefresh)
                {
                    entity = scopePathParser.Parse(objectPath).Value;

                    if (checkNulls && entity == null)
                        continue;

                    objectDAO.Refresh(entity);
                }
            }
            
            return CreateResult(successStatus);
        }

        private void AttachObject(object entity)
        {
            objectDAO.AttachToSession(entity);
        }

        private void AttachCollection(ICollection collection)
        {
            if (collection == null) return;
            
            foreach (object o in collection)
            {
                object entity = o;
                
                if (!StringUtils.IsNullOrEmpty(collectionPath))
                {
                    entity = scopePathParser.Parse(o, collectionPath).Value;
                }

                AttachObject(entity);
            }
        }
    }

}

